/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package org.cjava.system.bean.client;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.cjava.system.bean.IndexUserBean;
import org.cjava.system.model.Company;
import org.cjava.system.model.CompanyPersonProfile;
import org.cjava.system.model.Person;
import org.cjava.system.model.PersonProfile;
import org.cjava.system.model.Profile;
import org.cjava.system.model.SystemUser;
import org.cjava.system.model.extra.ResultCV;
import org.cjava.system.service.interfac.ICompanyPersonProfileService;
import org.cjava.system.service.interfac.ICompanyService;
import org.cjava.system.service.interfac.IPersonService;
import org.cjava.system.service.interfac.IProfileService;
import org.cjava.system.service.interfac.ISystemUserService;
import org.cjava.system.util.Clazz;
import org.cjava.system.util.ListUtilitary;
import org.cjava.system.util.faces.FacesUtil;
import org.omnifaces.util.Faces;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.DualListModel;
import org.primefaces.model.StreamedContent;

/**
 *
 * @author max
 */
@ManagedBean
@SessionScoped
public class CompanyBean implements Serializable {
private static final long serialVersionUID = 1L;
    @ManagedProperty("#{systemUserService}")
    ISystemUserService systemUserService;
    @ManagedProperty("#{companyService}")
    ICompanyService companyService;
    @ManagedProperty("#{profileService}")
    IProfileService profileService;
    @ManagedProperty("#{personService}")
    IPersonService personService;
    @ManagedProperty("#{companyPersonProfileService}")
    ICompanyPersonProfileService companyPersonProfileService;
    ////////////////FOR lOGGIN /////////////////
    private String userName;
    private String password;
    private Company company = new Company();
    private boolean showForm;
    
    ///////////////////////////////////////////
    private DualListModel<Profile> listDataBases;
    private DualListModel<Profile> listLanguages;
    private DualListModel<Profile> listCertifications;
    private DualListModel<Profile> listTools;
    private DualListModel<Profile> listFrameworks;
    ////////////////////////////////////////////////////
    private List<Profile> listResultSend = new ArrayList<>();
    private List<ResultCV> listResultCV = new ArrayList<>();
    /////////////////////////////////////////////
    private List<Company> listCompany;
    private List<Profile> listProfile;
    private List<Integer> listNumerSearch;

    public void initValuesForCreateCompany() {
        company = new Company();
        company.setSystemUserId(new SystemUser());
        company.getSystemUserId().setDescription("Usuario Empresa");
        company.getSystemUserId().setType(Clazz._TYPE_SYSTEM_USER._EMPRESA);
    }

    public void initValuesForViewCompany() {
        listCompany = null;
    }

    public void initValuesForHistory() {
        listNumerSearch = null;
        listProfile = null;
    }

    /**
     * PROCESAR INFORMACIÓN ACERCA DE LO SOLICITADO POR UNA EMPRESA
     * @throws Exception 
     */
    public void processInformationAssociate() throws Exception {
        // YA TENGO LA LSITA DE SOLICITUDES 
        //listProfile
        String hql = "select p.idPerson from PersonProfile p group by p.idPerson";
        List<Person> listTempPerson = personService.listHQL(hql, 1, null);
        System.out.println("Los que tienen persil: " + listTempPerson);
        List<Object[]> listPro = null;
        listResultCV = new ArrayList<>();
        //RECORRO A TODAS LAS PERSONA QUE TENGAN LLENADO SU CV EN LA PAGINA
        for (Person p : listTempPerson) {
            List<Profile> listProf = new ArrayList<>();
            //SEPARO A UNA LISTA APARTE TODO EL PERFIL DE CADA UNA DE LAS PERSONAS
            for (PersonProfile perPro : p.getPersonProfileList()) {
                listProf.add(perPro.getIdProfile());                
            }
            //REALIZO UN INTERSECCIÓN PARA PODER HACER UN CALCULO DEL PORCENTAJE DE VALIDEZ
            listPro = ListUtilitary.interseccionGen(listProfile, listProf);
            System.out.println("Interseccion: " + listPro);
            double _100Percent = listProfile.size();
            double percentPerPerson = ( listPro.size() * 100 ) / _100Percent;
            System.out.println("Total Percent For Person: " + Clazz.ROUND(percentPerPerson, 2));
            listResultCV.add(new ResultCV(listResultCV.size() + 1, p, Clazz.ROUND(percentPerPerson, 2)));
        }
        
        FacesUtil.addMessage("Información Procesada" , null, FacesMessage.SEVERITY_WARN);
    }
    
    public void changeNumberSearch(Integer number) throws Exception {

        String hql = "select c.idProfile from CompanyPersonProfile c where "
                + "c.idCompany.id=" + company.getId()
                + " and c.numberSearch=" + number;
        listProfile = profileService.listHQL(hql);

    }

    public void saveOrUpdateCompany() throws Exception {
        if (company.getId() == null) {
            company.getSystemUserId()
                    .setId(systemUserService.save(company.getSystemUserId()));
            companyService.save(company);
            initValuesForCreateCompany();
            FacesUtil.addMessage("Guardado con éxito.", null, FacesMessage.SEVERITY_INFO);
        } else {
            if (company.getSystemUserId().getId() == null) {
                company.getSystemUserId()
                        .setId(systemUserService.save(company.getSystemUserId()));
            } else {
                systemUserService.update(company.getSystemUserId());
            }

            companyService.update(company);
            initValuesForCreateCompany();
            FacesUtil.addMessage("Actualizado con éxito.", null, FacesMessage.SEVERITY_INFO);
        }

    }

    public void initValues() throws Exception {
        System.out.println("Ud. tiene => " + company.getNumberSearch() + " Busquedas");
        company = companyService.getByHQL("from Company c where c.id=" + company.getId());
        if (company.getNumberSearch() != null && company
                .getNumberSearch() >= 1) {

            showForm = true;
            initCollection();
        } else {
            FacesUtil.addMessage("UD. NO PUEDE REALZIAR BUSQUEDAS.",
                    null, FacesMessage.SEVERITY_WARN);
            showForm = false;
        }
    }

    public void initCollection() {
        listFrameworks = null;
        listDataBases = null;
        listLanguages = null;
        listCertifications = null;
        listTools = null;
    }

    public void sendInformation() throws Exception {

        System.out.println("Cer: " + listCertifications.getTarget());
        System.out.println("Data: " + listDataBases.getTarget());
        System.out.println("Fra: " + listFrameworks.getTarget());
        System.out.println("Len: " + listLanguages.getTarget());
        System.out.println("too: " + listTools.getTarget());
        if (listCertifications.getTarget().isEmpty()
                && listDataBases.getTarget().isEmpty()
                && listFrameworks.getTarget().isEmpty()
                && listLanguages.getTarget().isEmpty()
                && listTools.getTarget().isEmpty()) {

            FacesUtil.addMessage("NO SELEECCIONO NADA", null, FacesMessage.SEVERITY_ERROR);
            initCollection();
        } else {
            //todo code here
            //EL NUMERO DE BUSCQUEDAS REDUCE A UNO
            company.setNumberSearch(company.getNumberSearch() - 1);
            companyService.update(company);
            //AGREGAMOS TODO LO QUE SELECCIONO A UNA SOLA LISTA
            listResultSend = new ArrayList<>();
            listResultSend.addAll(listCertifications.getTarget());
            listResultSend.addAll(listDataBases.getTarget());
            listResultSend.addAll(listFrameworks.getTarget());
            listResultSend.addAll(listLanguages.getTarget());
            listResultSend.addAll(listTools.getTarget());
            //BUSCAMOS EL SIGUIENTE NUMERO DE BUSQUE DA QUE ESTA REALIZABDO
            String hql = "select max(c.numberSearch) from CompanyPersonProfile c "
                    + "where c.idCompany.id=" + company.getId();
            List<Integer> listMaxNS = companyService.listHQL(hql);
            Integer numberSeacr;
            System.out.println("max: " + listMaxNS.get(0));
            if (listMaxNS.get(0) == null) {
                //SI ES SU PRIMERA BUSQUEDA QUEDARA COMO 1
                numberSeacr = 1;
            } else {
                // SI YA TIENE MAS DE 1 BUSQUEDA DEBERA SUMAR UNO MAS
                numberSeacr = listMaxNS.get(0) + 1;
            }
            //AGREGAMOS A LA BASE DE DATOS TODOS LOS DETALLES DE BSUQUEDA
            for (int i = 0; i < listResultSend.size(); i++) {
                companyPersonProfileService
                        .save(new CompanyPersonProfile(
                                        numberSeacr,
                                        listResultSend.get(i),
                                        company
                                ));

            }
            //////////////////// MOSTRAMOS UN MENSAJE DE CONFIRMACIÓN
            FacesUtil.addMessage("Tu petición fué enviada a CJava Perú", null, FacesMessage.SEVERITY_INFO);
            FacesUtil.addMessage("Nos comunicaremos con Ud.", null, FacesMessage.SEVERITY_INFO);
            initValues();
            initCollection();

        }

    }

    public void loginClientCompany() throws Exception {
        Calendar cal = Calendar.getInstance();
        String hqlOrig = "from Company c where "
                + "c.systemUserId.type='(typex)' "
                + "and c.systemUserId.userName='(user)' "
                + "and c.systemUserId.password='(pass)'";
        hqlOrig = hqlOrig
                .replace("(typex)", Clazz._TYPE_SYSTEM_USER._EMPRESA)
                .replace("(user)", userName)
                .replace("(pass)", password);
        List<Company> listComTemp = companyService.listHQL(hqlOrig);

        if (listComTemp.isEmpty()) {
            FacesUtil.addMessage("Usuario o password incorrectos.", null, FacesMessage.SEVERITY_ERROR);
        } else {

            if (listComTemp.get(0).getSystemUserId().getFinishDate().before(cal.getTime())) {
//                System.out.println("La fecha se encuentra antes de la actual");
                FacesUtil.addMessage("Su cuenta está vencida..", null, FacesMessage.SEVERITY_WARN);
            } else {
                company = listComTemp.get(0);
                Faces.setSessionAttribute(FacesUtil.ATTRIBUTE_USER_COMPANY, company);
                Faces.redirect("index_empresa.jsf");
                FacesUtil.addMessage("Bienvenido...", null, FacesMessage.SEVERITY_INFO);

            }
        }
    }

    public void logOutClientcompany() {
        try {
            Faces.removeSessionAttribute(FacesUtil.ATTRIBUTE_USER_COMPANY);
            Faces.logout();
            Faces.invalidateSession();
            Faces.redirect("empresa.jsf");
        } catch (ServletException ex) {
            Logger.getLogger(IndexUserBean.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(IndexUserBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public DualListModel<Profile> getListDataBases() throws Exception {
        if (listDataBases == null) {
            String hql = "from Profile p "
                    + "where p.type='(type)' order by p.name";
            hql = hql.replace("(type)", Clazz._TYPE_PROFILE._DATABASE);
            List listProfileSrc = profileService.listHQL(hql);
            listDataBases = new DualListModel<>(listProfileSrc, new ArrayList<Profile>());
        }
        return listDataBases;
    }

    public DualListModel<Profile> getListLanguages() throws Exception {
        if (listLanguages == null) {
            String hql = "from Profile p "
                    + "where p.type='(type)' order by p.name";
            hql = hql.replace("(type)", Clazz._TYPE_PROFILE._LANGUAGE);
            List listProfileSrc = profileService.listHQL(hql);
            listLanguages = new DualListModel<>(listProfileSrc, new ArrayList<Profile>());
        }
        return listLanguages;
    }

    public DualListModel<Profile> getListCertifications() throws Exception {
        if (listCertifications == null) {
            String hql = "from Profile p "
                    + "where p.type='(type)' order by p.name";
            hql = hql.replace("(type)", Clazz._TYPE_PROFILE._CERTIFICATION);
            List listProfileSrc = profileService.listHQL(hql);
            listCertifications = new DualListModel<>(listProfileSrc, new ArrayList<Profile>());
        }
        return listCertifications;
    }

    public DualListModel<Profile> getListTools() throws Exception {
        if (listTools == null) {
            String hql = "from Profile p "
                    + "where p.type='(type)' order by p.name";
            hql = hql.replace("(type)", Clazz._TYPE_PROFILE._TOOLS);
            List listProfileSrc = profileService.listHQL(hql);
            listTools = new DualListModel<>(listProfileSrc, new ArrayList<Profile>());
        }
        return listTools;
    }

    public DualListModel<Profile> getListFrameworks() throws Exception {
        if (listFrameworks == null) {
            String hql = "from Profile p "
                    + "where p.type='(type)' order by p.name";
            hql = hql.replace("(type)", Clazz._TYPE_PROFILE._FRAMEWORK_JAVA);
            List listProfileSrc = profileService.listHQL(hql);
            listFrameworks = new DualListModel<>(listProfileSrc, new ArrayList<Profile>());
        }
        return listFrameworks;
    }

    public List<Company> getListCompany() throws Exception {
        if (listCompany == null) {
            String hql = "from Company c";
            listCompany = companyService.listHQL(hql);
        }
        return listCompany;
    }

    public void setListCompany(List<Company> listCompany) {
        this.listCompany = listCompany;
    }

    public List<Profile> getListProfile() throws Exception {
        if (listProfile == null) {
            String hql = "select c.idProfile from CompanyPersonProfile c where "
                    + "c.idCompany.id=" + company.getId()
                    + " and c.numberSearch=1";
            listProfile = profileService.listHQL(hql);
        }
        return listProfile;
    }

    public void setListProfile(List<Profile> listProfile) {
        this.listProfile = listProfile;
    }

    public void setProfileService(IProfileService profileService) {
        this.profileService = profileService;
    }

    public List<Integer> getListNumerSearch() throws Exception {
        if (listNumerSearch == null) {
            String hql = "select c.numberSearch from"
                    + " CompanyPersonProfile c"
                    + " where c.idCompany.id=(idComp)"
                    + " group by c.numberSearch";
            hql = hql.replace("(idComp)", "" + company.getId());
            listNumerSearch = companyService.listHQL(hql);
        }
        return listNumerSearch;
    }

    public List<ResultCV> getListResultCV() {
        return listResultCV;
    }

    public void setListResultCV(List<ResultCV> listResultCV) {
        this.listResultCV = listResultCV;
    }

    public void setListNumerSearch(List<Integer> listNumerSearch) {
        this.listNumerSearch = listNumerSearch;
    }

    public void setPersonService(IPersonService personService) {
        this.personService = personService;
    }

    

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public boolean isShowForm() {
        return showForm;
    }

    public void setShowForm(boolean showForm) {
        this.showForm = showForm;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setSystemUserService(ISystemUserService systemUserService) {
        this.systemUserService = systemUserService;
    }

    public void setCompanyService(ICompanyService companyService) {
        this.companyService = companyService;
    }

    public void setCompanyPersonProfileService(ICompanyPersonProfileService companyPersonProfileService) {
        this.companyPersonProfileService = companyPersonProfileService;
    }

    public Company getCompany() {
        return company;
    }

    public void setCompany(Company company) {
        this.company = company;
    }

    public void setListDataBases(DualListModel<Profile> listDataBases) {
        this.listDataBases = listDataBases;
    }

    public void setListLanguages(DualListModel<Profile> listLanguages) {
        this.listLanguages = listLanguages;
    }

    public void setListCertifications(DualListModel<Profile> listCertifications) {
        this.listCertifications = listCertifications;
    }

    public void setListTools(DualListModel<Profile> listTools) {
        this.listTools = listTools;
    }

    public void setListFrameworks(DualListModel<Profile> listFrameworks) {
        this.listFrameworks = listFrameworks;
    }

    public List<Profile> getListResultSend() {
        return listResultSend;
    }

    public void setListResultSend(List<Profile> listResultSend) {
        this.listResultSend = listResultSend;
    }

}
